mod input_method;
mod hotkey;
mod single_instance;
mod logger;
mod config;

use clap::Parser;

use input_method::InputMethodManager;
use logger::init_logger;
use log::info;
use config::Config;

#[derive(Parser)]
#[command(name = "im-select-ms")]
#[command(about = "Windows 输入法切换工具")]
#[command(version)]
struct Args {
    /// 输入法ID，直接切换到此输入法
    input_method_id: Option<i32>,

    /// 子命令
    #[command(subcommand)]
    command: Option<Commands>,
}

#[derive(Parser)]
enum Commands {
    /// 配置管理
    Config {
        /// 子命令
        #[command(subcommand)]
        subcommand: ConfigSubcommand,
    },
    /// 启动守护进程
    Start,
    /// 停止守护进程
    Stop,
    /// 测试热键功能
    Test,
}

#[derive(Parser)]
enum ConfigSubcommand {
    /// 显示所有配置
    Show,
    /// 获取配置值
    Get {
        /// 配置项名称
        key: String,
    },
    /// 设置配置值
    Set {
        /// 配置项名称
        key: String,
        /// 配置值
        value: String,
    },
}

fn main() -> Result<(), Box<dyn std::error::Error>> {
    init_logger();
    info!("程序启动");
    let args = Args::parse();

    // 处理子命令
    if let Some(command) = args.command {
        match command {
            Commands::Config { subcommand } => {
                match subcommand {
                    ConfigSubcommand::Show => {
                        let config = Config::load()?;
                        println!("当前配置:");
                        println!("  input_methods: {}", config.get_value("input_methods").unwrap_or_else(|| "[]".to_string()));
                        println!("  auto_start: {}", config.get_value("auto_start").unwrap_or_else(|| "false".to_string()));
                    },
                    ConfigSubcommand::Get { key } => {
                        let config = Config::load()?;
                        if let Some(value) = config.get_value(&key) {
                            println!("{}", value);
                        } else {
                            println!("未知配置项: {}", key);
                        }
                    },
                    ConfigSubcommand::Set { key, value } => {
                        let mut config = Config::load()?;
                        config.set_value(&key, &value)?;
                        config.save()?;
                        println!("已设置 {} = {}", key, value);
                    },
                }
                return Ok(());
            },
            Commands::Start => {
                let daemon_path = std::env::current_exe()?.parent().unwrap().join("im-select-daemon.exe");
                
                // 检查守护进程文件是否存在
                if !daemon_path.exists() {
                    return Err("守护进程文件不存在，请先编译项目".into());
                }
                
                // 检查是否已经有守护进程在运行
                let pid_file = dirs::home_dir()
                    .unwrap_or_else(|| std::path::PathBuf::from("."))
                    .join(".utopia")
                    .join("im-select-daemon.pid");
                
                if pid_file.exists() {
                    if let Ok(pid_str) = std::fs::read_to_string(&pid_file) {
                        if let Ok(pid) = pid_str.trim().parse::<u32>() {
                            unsafe {
                                let handle = winapi::um::processthreadsapi::OpenProcess(
                                    winapi::um::winnt::PROCESS_QUERY_INFORMATION,
                                    0,
                                    pid,
                                );
                                if !handle.is_null() {
                                    winapi::um::handleapi::CloseHandle(handle);
                                    println!("守护进程已在运行 (PID: {})", pid);
                                    println!("热键监听已激活，按 Ctrl+Space 切换输入法");
                                    return Ok(());
                                }
                            }
                        }
                    }
                    // PID文件存在但进程不存在，删除PID文件
                    let _ = std::fs::remove_file(&pid_file);
                }
                
                println!("正在启动守护进程...");
                let mut cmd = std::process::Command::new(&daemon_path);
                let mut child = cmd.spawn()?;
                
                // 等待守护进程启动并初始化
                let mut attempts = 0;
                const max_attempts: u32 = 20; // 最多等待10秒
                
                let status_file = dirs::home_dir()
                    .unwrap_or_else(|| std::path::PathBuf::from("."))
                    .join(".utopia")
                    .join("im-select-daemon.status");
                
                while attempts < max_attempts {
                    std::thread::sleep(std::time::Duration::from_millis(500));
                    attempts += 1;
                    
                    // 检查进程是否还在运行
                    match child.try_wait() {
                        Ok(None) => {
                            // 进程还在运行，检查状态文件是否已创建
                            if status_file.exists() {
                                if let Ok(status_content) = std::fs::read_to_string(&status_file) {
                                    if status_content.trim() == "ready" {
                                        if let Ok(pid_str) = std::fs::read_to_string(&pid_file) {
                                            if let Ok(pid) = pid_str.trim().parse::<u32>() {
                                                println!("守护进程已启动 (PID: {})", pid);
                                                println!("热键监听已激活，按 Ctrl+Space 切换输入法");
                                                return Ok(());
                                            }
                                        }
                                    }
                                }
                            }
                        },
                        Ok(Some(status)) => {
                            return Err(format!("守护进程启动失败，退出状态: {}", status).into());
                        },
                        Err(e) => {
                            return Err(format!("检查守护进程状态失败: {}", e).into());
                        }
                    }
                }
                
                // 如果超时，尝试强制终止进程并返回错误
                let _ = child.kill();
                return Err("守护进程启动超时，请检查日志文件".into());
            },
            Commands::Stop => {
                let daemon_path = std::env::current_exe()?.parent().unwrap().join("im-select-daemon.exe");
                
                // 检查守护进程文件是否存在
                if !daemon_path.exists() {
                    return Err("守护进程文件不存在，请先编译项目".into());
                }
                
                // 方法1: 通过守护进程的stop参数停止
                let mut cmd = std::process::Command::new(&daemon_path);
                cmd.arg("--stop");
                let status = cmd.status();
                
                if let Ok(status) = status {
                    if status.success() {
                        println!("守护进程已停止");
                        return Ok(());
                    } else {
                        println!("通过守护进程停止失败，尝试强制终止...");
                    }
                } else {
                    println!("无法启动守护进程停止命令，尝试强制终止...");
                }
                
                // 方法2: 通过PID文件强制终止进程
                let pid_file = dirs::home_dir()
                    .unwrap_or_else(|| std::path::PathBuf::from("."))
                    .join(".utopia")
                    .join("im-select-daemon.pid");
                
                if let Ok(pid_str) = std::fs::read_to_string(&pid_file) {
                    if let Ok(pid) = pid_str.trim().parse::<u32>() {
                        unsafe {
                            let handle = winapi::um::processthreadsapi::OpenProcess(
                                winapi::um::winnt::PROCESS_TERMINATE,
                                0,
                                pid,
                            );
                            if !handle.is_null() {
                                let result = winapi::um::processthreadsapi::TerminateProcess(handle, 0);
                                winapi::um::handleapi::CloseHandle(handle);
                                if result != 0 {
                                    println!("守护进程已强制终止 (PID: {})", pid);
                                    // 删除PID文件
                                    let _ = std::fs::remove_file(&pid_file);
                                    return Ok(());
                                } else {
                                    println!("终止进程失败");
                                }
                            } else {
                                println!("未找到守护进程 (PID: {})", pid);
                            }
                        }
                    }
                }
                
                // 方法3: 通过进程名查找并终止
                println!("尝试通过进程名查找并终止...");
                let mut cmd = std::process::Command::new("taskkill");
                cmd.args(&["/F", "/IM", "im-select-daemon.exe"]);
                let status = cmd.status();
                
                if let Ok(status) = status {
                    if status.success() {
                        println!("通过taskkill成功终止守护进程");
                        return Ok(());
                    } else {
                        println!("守护进程可能已经停止或不存在");
                        return Ok(());
                    }
                } else {
                    println!("无法执行taskkill命令");
                    return Ok(());
                }
            },
            Commands::Test => {
                let daemon_path = std::env::current_exe()?.parent().unwrap().join("im-select-daemon.exe");
                
                // 检查守护进程文件是否存在
                if !daemon_path.exists() {
                    return Err("守护进程文件不存在，请先编译项目".into());
                }
                
                let mut cmd = std::process::Command::new(&daemon_path);
                cmd.arg("--test");
                let status = cmd.status()?;
                
                if status.success() {
                    println!("热键测试完成");
                } else {
                    println!("热键测试失败，退出状态: {}", status);
                }
                return Ok(());
            },
        }
    }

    // 直接切换到指定输入法
    if let Some(locale) = args.input_method_id {
        info!("切换到指定输入法: {}", locale);
        let mut manager = InputMethodManager::new(vec![locale]);
        manager.switch_to_input_method(locale);
        println!("已切换到输入法: {} ({})", locale, InputMethodManager::get_input_method_name(locale));
        return Ok(());
    }

    // 默认行为：显示当前输入法
    let current_im = InputMethodManager::get_current_input_method();
    println!("当前输入法: {} ({})", current_im, InputMethodManager::get_input_method_name(current_im));

    Ok(())
}